#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Foxglove运行线程
负责在后台执行Foxglove检测、安装和启动任务
"""

import os
import sys
import time
import subprocess
import psutil
from pathlib import Path
from PySide2.QtCore import QThread, Signal
from mooetoolapp.handlercore.language_manager import LanguageManager

try:
    import winapps
except ImportError:
    winapps = None

try:
    from gglobal import logger
except ImportError:
    import logging
    logger = logging.getLogger(__name__)

class RunFoxgloveThread(QThread):
    """Foxglove运行线程类"""
    
    # 信号定义
    status_updated = Signal(str)  # 状态更新信号
    installation_progress = Signal(int)  # 安装进度信号
    foxglove_started = Signal()  # Foxglove启动成功信号
    foxglove_already_running = Signal()  # Foxglove已运行信号
    installation_requested = Signal(str)  # 安装请求信号
    error_occurred = Signal(str)  # 错误信号
    
    def __init__(self, installer_path=None, parent=None):
        super().__init__(parent)
        self.installer_path = installer_path
        self.is_cancelled = False
        
        # 初始化语言管理器
        self.language_manager = LanguageManager()
        
    def run(self):
        """线程主执行函数"""
        try:
            logger.info(self.language_manager.get_text("foxglove_checking_install", category="constants"))
            
            # 1. 检查Foxglove是否已安装
            self.status_updated.emit(self.language_manager.get_text("foxglove_checking_install", category="constants"))
            
            foxglove_path = self._is_foxglove_installed()
            if not foxglove_path:
                logger.info(self.language_manager.get_text("foxglove_not_installed", category="constants"))
                self.status_updated.emit(self.language_manager.get_text("foxglove_not_installed", category="constants"))
                
                # 发射安装请求信号
                if self.installer_path:
                    self.installation_requested.emit(self.installer_path)
                else:
                    self.error_occurred.emit(self.language_manager.get_text("foxglove_installer_not_found", category="constants"))
                return
            
            # 2. 检查Foxglove是否已在运行
            self.status_updated.emit(self.language_manager.get_text("foxglove_checking_running", category="constants"))
            
            if self._is_foxglove_running():
                logger.info(self.language_manager.get_text("foxglove_already_running", category="constants"))
                self.status_updated.emit(self.language_manager.get_text("foxglove_already_running", category="constants"))
                self.foxglove_already_running.emit()
                return
            
            # 3. 启动Foxglove
            self.status_updated.emit(self.language_manager.get_text("foxglove_starting", category="constants"))
            
            if self._launch_foxglove():
                # 等待一段时间，然后检查是否成功启动
                time.sleep(3)
                
                if self._is_foxglove_running():
                    logger.info(self.language_manager.get_text("foxglove_start_success", category="constants"))
                    self.status_updated.emit(self.language_manager.get_text("foxglove_start_success", category="constants"))
                self.foxglove_started.emit()
            else:
                self.error_occurred.emit(self.language_manager.get_text("foxglove_start_failed", category="constants"))
                
        except Exception as e:
            logger.error(f"Foxglove操作过程中发生错误：{e}")
            self.error_occurred.emit(self.language_manager.get_text("foxglove_launch_error", category="constants").format(error=str(e)))
    
    def _is_foxglove_installed(self):
        """检查Foxglove是否已安装，返回安装路径或None"""
        try:
            # 检查常见的Foxglove安装路径
            possible_paths = [
                Path(os.path.expanduser("~")) / "AppData" / "Local" / "Programs" / "foxglove.exe",
                Path(os.path.expanduser("~")) / "AppData" / "Local" / "Programs" / "Foxglove" / "foxglove.exe",
                Path("C:") / "Program Files" / "Foxglove Studio" / "Foxglove Studio.exe",
                Path("C:") / "Program Files (x86)" / "Foxglove Studio" / "Foxglove Studio.exe",
            ]
            
            for path in possible_paths:
                if path.exists():
                    logger.info(f"找到Foxglove安装路径: {path}")
                    return str(path)
            
            # 使用winapps库检查已安装软件（备用方案）
            if winapps:
                try:
                    for app in winapps.list_installed():
                        if app.name and "foxglove" in app.name.lower():
                            logger.info(f"通过winapps找到Foxglove: {app.name} (版本: {app.version})")
                            # 尝试从注册表或常见位置推断路径
                            for path in possible_paths:
                                if path.exists():
                                    return str(path)
                except Exception as e:
                    logger.warning(f"使用winapps检查时出错: {e}")
            
            logger.info("未找到Foxglove安装")
            return None
            
        except Exception as e:
            logger.error(f"检查Foxglove安装状态时出错: {e}")
            return None
    
    def _is_foxglove_running(self):
        """检查Foxglove是否正在运行"""
        try:
            for proc in psutil.process_iter(['pid', 'name', 'exe']):
                try:
                    proc_info = proc.info
                    if proc_info['name'] and 'foxglove' in proc_info['name'].lower():
                        logger.info(f"找到运行中的Foxglove进程: {proc_info['name']} (PID: {proc_info['pid']})")
                        return True
                    
                    if proc_info['exe'] and 'foxglove' in proc_info['exe'].lower():
                        logger.info(f"找到运行中的Foxglove进程: {proc_info['exe']} (PID: {proc_info['pid']})")
                        return True
                        
                except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
                    continue
            
            logger.info("未找到运行中的Foxglove进程")
            return False
            
        except Exception as e:
            logger.error(f"检查Foxglove运行状态时出错: {e}")
            return False
    
    def _launch_foxglove(self):
        """启动Foxglove"""
        try:
            # 获取实际的安装路径
            foxglove_path = self._is_foxglove_installed()
            
            # 构建启动命令列表
            launch_commands = [
                ["foxglove"],
                ["start", "foxglove"],
            ]
            
            # 如果找到了实际安装路径，优先使用它
            if foxglove_path:
                launch_commands.insert(0, [foxglove_path])  # 将实际路径放在最前面
            
            # 添加其他可能的路径作为备用
            backup_paths = [
                str(Path(os.path.expanduser("~")) / "AppData" / "Local" / "Programs" / "foxglove.exe"),
                str(Path(os.path.expanduser("~")) / "AppData" / "Local" / "Programs" / "Foxglove" / "foxglove.exe"),
                str(Path("C:") / "Program Files" / "Foxglove Studio" / "Foxglove Studio.exe"),
                str(Path("C:") / "Program Files (x86)" / "Foxglove Studio" / "Foxglove Studio.exe"),
            ]
            
            for backup_path in backup_paths:
                if backup_path != foxglove_path:  # 避免重复
                    launch_commands.append([backup_path])
            
            for cmd in launch_commands:
                try:
                    if cmd[0].startswith('C:') or cmd[0].startswith(os.path.expanduser("~")):
                        # 检查可执行文件是否存在
                        if not Path(cmd[0]).exists():
                            continue
                    
                    logger.info(f"尝试启动命令: {' '.join(cmd)}")
                    
                    if cmd[0] == "start":
                        # Windows系统：添加CREATE_NO_WINDOW标志隐藏命令行窗口
                        subprocess.Popen(cmd, shell=True, creationflags=subprocess.CREATE_NO_WINDOW)
                    else:
                        # Windows系统：添加CREATE_NO_WINDOW标志隐藏命令行窗口
                        subprocess.Popen(cmd, creationflags=subprocess.CREATE_NO_WINDOW)
                    
                    logger.info("Foxglove启动命令执行成功")
                    return True
                    
                except (FileNotFoundError, subprocess.SubprocessError) as e:
                    logger.debug(f"启动命令失败: {' '.join(cmd)}, 错误: {e}")
                    continue
            
            logger.error("所有Foxglove启动方式都失败")
            return False
            
        except Exception as e:
            logger.error(f"启动Foxglove时出错: {e}")
            return False
    
    def cancel(self):
        """取消当前任务"""
        self.is_cancelled = True
        logger.info("Foxglove线程任务已取消")
    
    def cleanup(self):
        """清理资源"""
        self.cancel()
        if self.isRunning():
            self.quit()
            self.wait(3000)  # 等待最多3秒
        logger.info("RunFoxgloveThread资源清理完成")